/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs     (C)ChaN, 2007        */
/*-----------------------------------------------------------------------*/
/* by grqd_xp                                                            */
/* This is a stub disk I/O module that acts as front end of the existing */
/* disk I/O modules and attach it to FatFs module with common interface. */
/*-----------------------------------------------------------------------*/
#include <string.h>
#include "diskio.h"
#include "sdcard.h"

/*-----------------------------------------------------------------------*/
/* Correspondence between physical drive number and physical drive.      */
/* Note that Tiny-FatFs supports only single drive and always            */
/* accesses drive number 0.                                              */

#define SECTOR_SIZE 512U
SD_CardInfo SDCardInfo2; 

//u32 buff2[512/4];
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */

DSTATUS disk_initialize (
	BYTE drv				/* Physical drive nmuber (0..) */
)
{
    NVIC_InitTypeDef NVIC_InitStructure; 

    SD_Init(); 
    SD_GetCardInfo(&SDCardInfo2); 
    SD_SelectDeselect((uint32_t) (SDCardInfo2.RCA << 16)); 
    SD_EnableWideBusOperation(SDIO_BusWide_4b); 
    SD_SetDeviceMode(SD_DMA_MODE); 

    NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn; 
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure); 

    return 0; 
}



/*-----------------------------------------------------------------------*/
/* Return Disk Status                                                    */

DSTATUS disk_status (
	BYTE drv		/* Physical drive nmuber (0..) */
)
{	
	return 0;
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s)                                                        */

DRESULT disk_read (
	BYTE drv,		/* Physical drive nmuber (0..) */
	BYTE *buff,		/* Data buffer to store read data */
	DWORD sector,	/* Sector address (LBA) */
	BYTE count		/* Number of sectors to read (1..255) */
)
{ 
	if(count==1)
        SD_ReadBlock(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE);
	else
        SD_ReadMultiBlocks(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE,count);

	return RES_OK;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s)                                                       */

#if _READONLY == 0
DRESULT disk_write (
	BYTE drv,			/* Physical drive nmuber (0..) */
	const BYTE *buff,	/* Data to be written */
	DWORD sector,		/* Sector address (LBA) */
	BYTE count			/* Number of sectors to write (1..255) */
)
{
	if(count==1)
        SD_WriteBlock(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE);
	else
        SD_WriteMultiBlocks(sector << 9 ,(u32 *)(&buff[0]),SECTOR_SIZE,count);
        
  return RES_OK;
}
#endif /* _READONLY */



/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions                                               */

DRESULT disk_ioctl (
	BYTE drv,		/* Physical drive nmuber (0..) */
	BYTE ctrl,		/* Control code */
	void *buff		/* Buffer to send/receive control data */
)
{
    DRESULT res = RES_OK; 
    uint32_t status = SD_NO_TRANSFER; 

    switch (ctrl) 
    { 
        case CTRL_SYNC :            // Make sure that no pending write process 
            status = SD_GetTransferState(); 
            if (status == SD_NO_TRANSFER) 
                res = RES_OK;
            else{res = RES_ERROR;} 
                break; 

        case GET_SECTOR_COUNT :     // Get number of sectors on the disk (DWORD) 
            *(DWORD*)buff = 131072; // 4*1024*32 = 131072 // 64MO
            res = RES_OK; 
            break; 

        case GET_SECTOR_SIZE :      // Get R/W sector size (WORD)  
            *(WORD*)buff = 512; 
            res = RES_OK; 
            break; 

        case GET_BLOCK_SIZE :       // Get erase block size in unit of sector (DWORD) 
            *(DWORD*)buff = 32; 
            res = RES_OK; 
    } 

    return res; 
}

DWORD get_fattime(void){
    return ((2011UL-1980) << 25)       // Year = 2006 
        | (3UL << 21)       // Month = Feb 
        | (31UL << 16)       // Day = 9 
        | (22U << 11)       // Hour = 22 
        | (30U << 5)       // Min = 30 
        | (0U >> 1)       // Sec = 0 
        ; 
}























